﻿namespace FietsenManagementJB
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Linq;
    using System.Windows.Forms;

    public partial class MainFM : Form
    {
        private BikeController controller;
        private bool bikeChangedFlag;

        public MainFM()
        {
            controller = new BikeController();
            InitializeComponent();
            AdditionalConfig();
            LoadBikes();
            //ImportProcedure();
            FixColumnWidth();
            bikeChangedFlag = false;
        }

        private void ImportProcedure()
        {
            bikeDataGridView.DataSource = null;
            bikeDataGridView.DataSource = controller.importProcedure();
            bikeDataGridView.Refresh();
        }

        private void AdditionalConfig()
        {
            // Register controls for validation
            controller.RegisteredForValidation.Add(new Tuple<ValidationType, Control>(ValidationType.NotNull, nameTextBox));
            controller.RegisteredForValidation.Add(new Tuple<ValidationType, Control>(ValidationType.NumericCurrency, buyTextBox));
            controller.RegisteredForValidation.Add(new Tuple<ValidationType, Control>(ValidationType.NumericCurrency, investTextBox));
            controller.RegisteredForValidation.Add(new Tuple<ValidationType, Control>(ValidationType.Numeric, frameTextBox));
            genderComboBox.SelectedIndex = 0;
            fietsPictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
        }

        private void FixColumnWidth()
        {
            bikeDataGridView.Columns[0].Width = 150;
            bikeDataGridView.Columns[1].Width = 90;
            bikeDataGridView.Columns[1].DefaultCellStyle.Format = "C";
            bikeDataGridView.Columns[2].Width = 100;
            bikeDataGridView.Columns[2].DefaultCellStyle.Format = "dd/MM/yyyy";
            bikeDataGridView.Columns[3].Width = 90;
            bikeDataGridView.Columns[3].DefaultCellStyle.Format = "dd/MM/yyyy";
            bikeDataGridView.Columns[4].Width = 70;
            bikeDataGridView.Columns[5].Width = 70;
            bikeDataGridView.Columns[5].DefaultCellStyle.Format = "C";
            bikeDataGridView.Columns[6].Width = 100;
            bikeDataGridView.Columns[7].Width = 80;
            bikeDataGridView.Columns[7].DefaultCellStyle.Format = "C";
            bikeDataGridView.Columns[8].Width = 80;
            bikeDataGridView.Columns[8].DefaultCellStyle.Format = "C";
            bikeDataGridView.Columns[9].Width = 60;
            bikeDataGridView.Columns[10].Width = 100;
        }

        private void LoadBikes()
        {
            var bikes = controller.LoadBikes();
            if (bikes.Count > 0)
            {
                loadBike(bikes.FirstOrDefault().Id);
            }
            bikeDataGridView.DataSource = bikes;
        } 

        private void loadBike(int id)
        {
            var bike = controller.LoadBike(id);
            if (bike != null)
            {
                nameTextBox.Text = bike.Type;
                buyDateTimePicker.Value = bike.BuyDate;
                buyTextBox.Text = Math.Round(bike.BuyPrice,2).ToString("C");
                soldCheckBox.Checked = bike.Sold;
                if (bike.SellDate != DateTime.Parse("31-12-1752 23:00:00"))
                    sellDateTimePicker.Value = bike.SellDate.Value;
                sellTextBox.Text = Math.Round(bike.SellPrice).ToString("C");
                locationTextBox.Text = bike.LocationBought;
                investTextBox.Text = Math.Round(bike.InvestmentPrice).ToString("C");
                fietsPictureBox.Image = Image.FromFile(bike.BikePicture);
                bike.BikePicture = bike.BikePicture;
                genderComboBox.SelectedItem = bike.Gender;
                frameTextBox.Text = bike.Frame.ToString();
                frameNrTextBox.Text = bike.FrameNr;
                balanceTextBox.Text = controller.CalcBalance().ToString("C");
            }
        }

        private bool TryParseDecimalOrInt(Type type, TextBox textbox)
        {
            var validated = true;
            if (textbox.Text.Length < 1)
                return false;
            if (type == typeof(decimal))
            {
                decimal i;
                // Substring(1) for euro sign 
                if (!decimal.TryParse(textbox.Text.Substring(1), out i))
                {
                    textbox.BackColor = Color.Red;
                    validated = false;
                }
            }
            if (type == typeof(int))
            {
                int i;
                if (!int.TryParse(textbox.Text, out i))
                {
                    textbox.BackColor = Color.Red;
                    MessageBox.Show(String.Format("Veld moet een numerieke waarde bevatten. Zonder komma waardes"));
                    validated = false;
                }
            }
            return validated;
        }

        #region Event Handlers       

        private void pictureUploadButton_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                var url = openFileDialog1.FileName;
                controller.ActiveBike.BikePicture = url;
                fietsPictureBox.Image = Image.FromFile(url);
            }
            bikeChangedFlag = true;
        }

        private void bikeDataGridView_SelectionChanged(object sender, EventArgs e)
        {
            if (bikeChangedFlag && MessageBox.Show("U heeft wijzigingen gedaan aan deze fiets, opslaan?", "Melding", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                updateBikeButton_Click(sender, e);
            }
            if (bikeDataGridView.SelectedRows.Count < 1)
                return;
            var selectedRow = bikeDataGridView.SelectedRows[0];
            loadBike(Int32.Parse(selectedRow.Cells["id"].Value.ToString()));
            bikeChangedFlag = false;
        }

        private void updateBikeButton_Click(object sender, EventArgs e)
        {
            bikeChangedFlag = false;
            Tuple<bool, List<string>> inputFeedback = controller.inputValidation();
            if (inputFeedback.Item1)
            {
                bikeDataGridView.DataSource = null;
                controller.updateActiveBike(nameTextBox.Text, genderComboBox.Text, buyDateTimePicker.Value, buyTextBox.Text.Substring(1),
                    sellTextBox.Text.Substring(1), locationTextBox.Text, investTextBox.Text.Substring(1), 
                    sellDateTimePicker.Value, 
                    frameTextBox.Text, frameNrTextBox.Text, soldCheckBox.Checked);
                bikeDataGridView.DataSource = controller.Bikes;
                bikeDataGridView.Refresh();
                FixColumnWidth();
                controller.SaveBikes();
            }
            else
            {
                var errorString = "";
                foreach (var error in inputFeedback.Item2)
                {
                    errorString = errorString + error + "\n";
                }
                MessageBox.Show(errorString, "Validatie fouten");
            }
        }

        private void saveBikeButton_Click(object sender, EventArgs e)
        {
            Tuple<bool, List<string>> inputFeedback = controller.inputValidation();
            if (inputFeedback.Item1)
            {
                bikeDataGridView.DataSource = null;
                controller.saveNewBike(genderComboBox.Text.ToString(), buyTextBox.Text.Substring(1),
                    sellTextBox.Text.Substring(1), locationTextBox.Text, investTextBox.Text.Substring(1),
                    sellDateTimePicker.Value, frameTextBox.Text, frameNrTextBox.Text);
                bikeDataGridView.DataSource = controller.Bikes;
                controller.SaveBikes();
                bikeDataGridView.CurrentCell = bikeDataGridView.Rows[bikeDataGridView.Rows.Count-1].Cells[0];
                bikeDataGridView.Refresh();
                FixColumnWidth();
            }
            else
            {
                var errorString = "";
                foreach (var error in inputFeedback.Item2)
                {
                    errorString = errorString + error + "\n";
                }
                MessageBox.Show(errorString, "Validatie fouten");
            }
        }

        private void bikeDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            bikeDataGridView_SelectionChanged(sender, e);
        }

        private void deleteBikeButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Weet u zeker dat u deze fiets wilt verwijderen?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                bikeDataGridView.DataSource = null;
                bikeDataGridView.ClearSelection();
                bikeDataGridView.DataSource = controller.DeleteActiveBike();
                bikeDataGridView.Refresh();
                FixColumnWidth();
            }
            bikeChangedFlag = false;
        }

        private void frameTextBox_Validating(object sender, CancelEventArgs e)
        {
            if (TryParseDecimalOrInt(typeof(int), frameTextBox))
                frameTextBox.BackColor = Color.White;
        }

        private void frameTextBox_TextChanged(object sender, EventArgs e)
        {
            int frameNr = int.TryParse(frameTextBox.Text, out frameNr) ? int.Parse(frameTextBox.Text) : 0;
            controller.ActiveBike.Frame = frameNr;
            bikeChangedFlag = true;
        }

        private void buyTextBox_Validating(object sender, CancelEventArgs e)
        {
            if (TryParseDecimalOrInt(typeof(decimal), buyTextBox))
                buyTextBox.BackColor = Color.White;
        }

        private void buyTextBox_TextChanged(object sender, EventArgs e)
        {
            decimal buyAmount = decimal.TryParse(buyTextBox.Text.Substring(1), out buyAmount) ? decimal.Parse(buyTextBox.Text.Substring(1)) : 0.0M;
            controller.ActiveBike.BuyPrice = buyAmount;
            balanceTextBox.Text = controller.CalcBalance().ToString("C");
            bikeChangedFlag = true;
        }

        private void sellTextBox_Validating(object sender, CancelEventArgs e)
        {
            if (TryParseDecimalOrInt(typeof(decimal), sellTextBox))
                sellTextBox.BackColor = Color.White;
        }

        private void sellTextBox_TextChanged(object sender, EventArgs e)
        {
            decimal sellAmount = 0.0M;
            if (sellTextBox.Text.Length > 0)
            {
               sellAmount = (decimal.TryParse(sellTextBox.Text.Substring(1), out sellAmount)) ? decimal.Parse(sellTextBox.Text.Substring(1)) : 0.0M;
               controller.ActiveBike.SellPrice = sellAmount;
            }
            balanceTextBox.Text = controller.CalcBalance().ToString("C");
            bikeChangedFlag = true;
        }

        private void investTextBox_Validating(object sender, CancelEventArgs e)
        {
            if (TryParseDecimalOrInt(typeof(decimal), investTextBox))
                investTextBox.BackColor = Color.White;
        }

        private void investTextBox_TextChanged(object sender, EventArgs e)
        {
            decimal investAmount = 0.0M;
            if (investTextBox.Text.Length > 0)
            {
                investAmount = (decimal.TryParse(investTextBox.Text.Substring(1), out investAmount)) ? decimal.Parse(investTextBox.Text.Substring(1)) : 0.0M;
                controller.ActiveBike.InvestmentPrice = investAmount;
            }
            balanceTextBox.Text = controller.CalcBalance().ToString("C");
            bikeChangedFlag = true;
        }

        private void frameNrTextBox_TextChanged(object sender, EventArgs e)
        {
            bikeChangedFlag = true;
        }

        private void MainFM_Resize(object sender, EventArgs e)
        {
            bikeDataGridView.Width = (60 * this.Width) / 100;
            fietsPictureBox.Width = (35 * this.Width) / 100;
            fietsPictureBox.Height = (45 * this.Height) / 100;
        }

        private void soldCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (soldCheckBox.Checked == true)
            {
                sellDateTimePicker.Enabled = true;
                sellDateTimePicker.Format = DateTimePickerFormat.Short;
                sellDateTimePicker.Value = DateTime.Now;
                controller.RegisteredForValidation.Add(new Tuple<ValidationType, Control>(ValidationType.NumericCurrency, sellTextBox));
                sellTextBox.Enabled = true;
                sellDateTimePicker.Enabled = true;
            }
            else
            {
                sellDateTimePicker.Enabled = false;
                TimeSpan time = new TimeSpan(113, 37, 0);
                sellDateTimePicker.Value = sellDateTimePicker.MinDate;
                sellDateTimePicker.Format = DateTimePickerFormat.Custom;
                sellDateTimePicker.CustomFormat = " ";
                var checkExsists = new Tuple<ValidationType, Control>(ValidationType.NumericCurrency, sellTextBox);
                if (controller.RegisteredForValidation.Contains(checkExsists))
                    controller.RegisteredForValidation.Remove(checkExsists);
                sellTextBox.Enabled = false;
                sellDateTimePicker.Enabled = false;
            }
            bikeChangedFlag = true;
        }

        private void backupButton_Click(object sender, EventArgs e)
        {
            if (controller.CreateBackup())
            {
                MessageBox.Show("Backup gemaakt!", "Backup");
            }
            else
            {
                MessageBox.Show("Backup maken mislukt!", "Backup");
            }
        }

        private void overviewButton_Click(object sender, EventArgs e)
        {
            var overview = new Overview();
            overview.fillComponents(controller);
        }

        private void buyDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            bikeChangedFlag = true;
        }

        private void sellDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            bikeChangedFlag = true;
        }

        private void genderComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            bikeChangedFlag = true;
        }

        private void nameTextBox_TextChanged(object sender, EventArgs e)
        {
            bikeChangedFlag = true;
        }

        #endregion 
    }

    public enum ValidationType
    {
        NotNull,
        NumericCurrency,
        Numeric
    }
}
